﻿using System;
using Windows.Foundation;

namespace MetroNextTools.NHelper
{
    /// <summary>
    /// 精度纠错的工具
    /// </summary>
    internal static class DoubleHelper
    {
        internal const double DBL_EPSILON_RELATIVE_1 = 1.1102230246251568E-16;

        internal static bool AreClose(double value1, double value2)
        {
            if (value1 == value2)
            {
                return true;
            }
            double num = (Math.Abs(value1) + Math.Abs(value2) + 10.0) * DBL_EPSILON_RELATIVE_1;
            double num2 = value1 - value2;
            return -num < num2 && num > num2;
        }
        public static bool AreClose(Size size1, Size size2)
        {
            return DoubleHelper.AreClose(size1.Width, size2.Width) && DoubleHelper.AreClose(size1.Height, size2.Height);
        }

        public static bool AreClose(Rect rect1, Rect rect2)
        {
            if (rect1.IsEmpty)
            {
                return rect2.IsEmpty;
            }
            return !rect2.IsEmpty && DoubleHelper.AreClose(rect1.X, rect2.X) && DoubleHelper.AreClose(rect1.Y, rect2.Y) && DoubleHelper.AreClose(rect1.Height, rect2.Height) && DoubleHelper.AreClose(rect1.Width, rect2.Width);
        }
        internal static bool GreaterThan(double value1, double value2)
        {
            return value1 > value2 && !DoubleHelper.AreClose(value1, value2);
        }
        public static bool GreaterThanOrClose(double value1, double value2)
        {
            return value1 > value2 || DoubleHelper.AreClose(value1, value2);
        }
        internal static bool IsZero(double value)
        {
            return Math.Abs(value) < 1.1102230246251567E-15;
        }
        public static bool LessThan(double value1, double value2)
        {
            return value1 < value2 && !DoubleHelper.AreClose(value1, value2);
        }
        public static bool LessThanOrClose(double value1, double value2)
        {
            return value1 < value2 || DoubleHelper.AreClose(value1, value2);
        }
        public static double Fractional(double value)
        {
            if (value <= 0.0)
            {
                return value - Math.Ceiling(value);
            }
            return value - Math.Floor(value);
        }
    }
}
